iT邦幫忙

2021 iThome 鐵人賽

DAY 21
0
自我挑戰組

30天Swift純Code之旅 - 鬧鐘篇系列 第 21

Swift純Code之旅 Day21. 「ViewController好亂(3) - MVC下的Button動作」

  • 分享至 

  • xImage
  •  

前言

將一些畫面相關元件跟Function從「MVCTestViewController」搬去「MVCTestView」後,
發生了三個Error。
昨天已經解決掉一個了,今天接著解決剩下兩個吧!

修理

1.「MVCTestViewController」內的Function找不到Label & textField了https://ithelp.ithome.com.tw/upload/images/20210930/20108999RoJ9uxDcsI.png

解決方法:

「MVCTestViewController」會找不到 Label & textField呢,是因為我們將它搬到「MVCTestView」裡面了
因此現在要在「MVCTestViewController」內,把「MVCTestView」給召喚出來

let mvcTestView = MVCTestView()

之後再覆寫 Function: 「loadView()」,並在裡面指定該ViewController的View

override func loadView() {
        // 將 MVCTestViewController 的 view 指定為 MVCTestView
        self.view = mvcTestView
    }

這樣子「MVCTestViewController」的View,就會是「MVCTestView」了
將著將有問題的Code

@objc func buttonAction() {
        self.label.text = self.textField.text
    }

更改為

@objc func buttonAction() {
        // mvcTestView內的Label.text = mvcTestView內的textField
        mvcTestView.label.text = mvcTestView.textField.text
    }

這樣整個「MVCTestViewController」就沒有錯誤囉!
https://ithelp.ithome.com.tw/upload/images/20211001/20108999LgqyFsHPff.png


2.Button的Function要如何設定呢? https://ithelp.ithome.com.tw/upload/images/20210930/201089996PR2eE2YWN.png

  1. 首先在View建立一個閉包

    var buttonAction: (() -> Void)?
    
  2. 接著建立一個Function,裡面放這個閉包

    @objc func buttonDidTap() {
            buttonAction?()
        }
    
  3. 接著幫該Button新增Function進去
    (Button必須用lazy var實作出來,button按鈕的功能才會生效)
    https://ithelp.ithome.com.tw/upload/images/20211001/20108999Yf8k8Bhxbk.png

這時候View的Code會如下

class MVCTestView: UIView {
    
    var buttonAction: (() -> Void)?
    
    // MARK: - Properties
    let textField: UITextField = {
        let textField = UITextField()
        textField.placeholder = "請輸入文字"
        textField.layer.borderWidth = 1
        textField.layer.cornerRadius = 10
        textField.borderStyle = .roundedRect
        return textField
    }()
    
    lazy var button: UIButton = {
        let button = UIButton()
        button.largeContentTitle = "123"
        button.setTitle("按我", for: .normal)
        button.setTitleColor(.brown, for: .normal)
        button.addTarget(self, action: #selector(buttonDidTap), for: .touchUpInside)
        return button
    }()
    
    let label: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 40)
        label.textAlignment = .center
        label.textColor = .systemBlue
        label.layer.borderWidth = 1
        label.layer.borderColor = UIColor.systemBlue.cgColor
        label.layer.cornerRadius = 30
        return label
    }()
    
    // initial
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = .white
        setViews()
        setLayouts()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @objc func buttonDidTap() {
        buttonAction?()
    }
    
    func setViews() {
        self.addSubview(textField)
        self.addSubview(button)
        self.addSubview(label)
    }
    
    func setLayouts() {
        textField.snp.makeConstraints { make in
            make.top.equalTo(self.safeAreaLayoutGuide).offset(50)
            make.centerX.equalTo(self)
            make.width.equalTo(300)
            make.height.equalTo(40)
        }
        
        button.snp.makeConstraints { make in
            make.top.equalTo(textField.snp.bottom).offset(30)
            make.centerX.equalTo(self)
            make.height.equalTo(40)
            make.width.equalTo(100)
        }
        
        label.snp.makeConstraints { make in
            make.height.equalTo(100)
            make.width.equalTo(300)
            make.top.equalTo(button.snp.bottom).offset(100)
            make.centerX.equalTo(self)
        }
    }
}

這時候執行看看吧!
疑?按了完全沒用欸

沒錯!那是因為還沒設定「MVCTestView」裡面的「ButtonDidTap」
設定方法很簡單,先到「MVCTestViewController」內,新增以下Code

 override func viewDidLoad() {
        super.viewDidLoad()
        // 設定mvcTestView內的buttonAction
        self.mvcTestView.buttonAction = buttonAction
    }

再執行看看吧!

這樣View就跟ViewController分開囉!
也可以看到ViewController內Code的行數剩下30幾行,先不論Bug好找,自己看了也舒服/images/emoticon/emoticon05.gif


上一篇
Swift純Code之旅 Day20. 「ViewController好亂(2) - MVC畫面分離」
下一篇
Swift純Code之旅 Day22. 「切割TableView(1) - 實作TableViewHeader」
系列文
30天Swift純Code之旅 - 鬧鐘篇30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言